﻿/*
 * Author: Branimir Topic (uxxx4663)
 * For: UC - ODD - Assignment 2B
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using System.Data;
using ARMS.Models;
using ARMS.BaseClasses;

namespace ARMS.Controllers
{
	public class BookingController : Controller
	{
        //NOTE: THE FOLLOWING CODE IS REMOVED AND MOVED TO Factory class in ARMS.BaseClasses
        //public const string LCUSTOMERS = "Customers";
        //public const string LSERVICES = "Services";
        //public const string LWORKERS = "Workers";
        //public const string CSHOP = "Shop";
        //public const string VERROR = "Error";
		public int shopid { get; set; }

		public BookingController()
		{
			//shopid = User shopid
			this.shopid = 1;
		}

		public ActionResult Index(BookingList b)
		{
			try
			{

                //ALL LINES ARE COMMENTED DUE TO CODE BEING REFACTORED
                //THE FOLLWOING CODE REMOVED DUE TO REFACTORING
                //BookingModel model = new BookingModel();

                BookingList bookings = new BookingList();
                
                if (b != null && b.ToList().Count > 0)
                {
                    bookings = b;
                }
                else
                {
                    // THE FOLLOWING CODE IS 
                    bookings = Factory.GetBookings(shopid, false);
                }

                //REFACTORING: THE FOLLOWING CODE IS REMOVED DUE TO REPETITION
                //ShopModel modelShop = new ShopModel();
                //Shop shop = new Shop();
                //shop = modelShop.GetShop(this.shopid);
				//ViewData[Factory.CSHOP] = shop;

                Factory.SetShop(shopid, this);
				return View("Index", bookings.ToList());
			}
			catch (Exception e)
			{
				HandleErrorInfo err = new HandleErrorInfo(e, "Booking", "Index");
				return View(Factory.VERROR, err);
			}
		}

		public ActionResult Search()
		{
			try
			{
                //InventoryModel modelServices = new InventoryModel();
                //DataTable services = modelServices.getServices(this.shopid);

                //if (services.Rows.Count < 1)
                //{
                //    throw new Exception("No services found for this shop!");
                //}

                //string text, value;
                //List<SelectListItem> serviceList = new List<SelectListItem>();

                //foreach (System.Data.DataRow row in services.Rows)
                //{
                //    value = row["id"].ToString();
                //    text = String.Format("{0}", row["Description"].ToString());
                //    serviceList.Add(new SelectListItem { Text = text, Value = value, Selected = false });
                //}

                //ShopModel modelShop = new ShopModel();
                //Shop shop = new Shop();
                //shop = modelShop.GetShop(this.shopid);

                //REFACTORED CODE BELOW
                ARMS.BaseClasses.Factory.SetShop(shopid, this);
                ARMS.BaseClasses.Factory.SetServiceList(shopid, this);

                BookingAdpter adaptor = new BookingAdpter();
                adaptor.shopid = this.shopid.ToString();
				//adaptor.shopid = this.shopid.ToString();

                //ViewData[Factory.CSHOP] = shop;
                //ViewData[Factory.LSERVICES] = serviceList;

				return View("Search", adaptor);
			}
			catch (Exception e)
			{
				HandleErrorInfo err = new HandleErrorInfo(e, "Booking", "Index");
				return View(Factory.VERROR, err);
			}
		}

		public ActionResult SearchBooking(BookingAdpter b, string usetimeframe, string datestampfrom, string datestampto)
		{
			try
			{
				BookingModel model = new BookingModel();
				BookingList bookings = new BookingList();

				if (b.id != null ||
					b.customerid != null ||
					b.customername != null ||
					b.serviceid != null ||
                    datestampfrom.Length > 0 ||
                    datestampto.Length > 0)
				{
                    DateTime fromDate = DateTime.Today;
                    DateTime toDate = DateTime.Today;

                    if (Convert.ToBoolean(usetimeframe))
                    {
                        try
                        {
                            fromDate = ARMS.BaseClasses.ARMSConverter.ToDateTime(datestampfrom, false);
                        }
                        catch (Exception e)
                        {
                            ModelState.AddModelError("datestampfrom", "Invalid datetime format!");
                            return this.Search();
                        }

                        try
                        {
                            toDate = ARMS.BaseClasses.ARMSConverter.ToDateTime(datestampto, false);
                        }
                        catch (Exception e)
                        {
                            ModelState.AddModelError("datestampto", "Invalid datetime format!");
                            return this.Search();
                        }
                    }
                    bookings = model.GetBookings(b.instance, fromDate, toDate);
				}
				else
				{
					bookings = model.GetBookings(b.instance.id, b.instance.active);
				}

                Factory.SetShop(shopid, this);

				return this.Index(bookings);
			}
			catch (Exception e)
			{
				HandleErrorInfo err = new HandleErrorInfo(e, "Booking", "Search");
				return View(Factory.VERROR, err);
			}
		}

		public ActionResult MakeBooking(Booking booking)
		{
			try
			{
				// get the user authentication and the shop id he's assigned to;
				// this functionality is not going to be implemented for presentation mode

                Factory.SetServiceList(shopid, this);
                Factory.SetShop(shopid, this);

                booking.id = Helper.DummyValue;
                booking.shopid = this.shopid;
                
                if (booking.datestamp < DateTime.Now) booking.datestamp = DateTime.Now;
               
                booking.active = true;

				return View("MakeBooking", booking);
			}
			catch (Exception e)
			{
				HandleErrorInfo err = new HandleErrorInfo(e, "Main", "Index");
				return View(Factory.VERROR, err);
			}
		}

		public ActionResult FinaliseBooking(Booking booking)
		{
			try
			{
				if (!ModelState.IsValid) return this.MakeBooking(booking); 

                try
                {
                    Factory.SetCustomerList(shopid, "", booking.customername, this);
                }
                catch (Exception e)
                {
                    ModelState.AddModelError("customerid", e.Message);
                    return this.MakeBooking(booking);
                }

                Factory.SetServiceList(shopid, this);
                Factory.SetCustomerList(shopid, "", booking.customername, this);
                Factory.SetWorkerList(shopid, this);

				return View("Detail", booking);
			}
			catch (Exception e)
			{
				HandleErrorInfo err = new HandleErrorInfo(e, "Booking", "MakeBooking");
				return View(Factory.VERROR, err);
			}
		}

		public ActionResult Detail(string bookingid)
		{
			try
			{
				int bookingID = ARMSConverter.ToInt(bookingid, Helper.DummyValue, true);

				BookingModel model = new BookingModel();
				Booking booking = model.FindBooking(bookingID);

                Factory.SetShop(shopid, this);
                Factory.SetWorkerList(shopid, this);
                Factory.SetServiceList(shopid, this);

				return View("Detail", booking);
			}
			catch (Exception e)
			{
				HandleErrorInfo err = new HandleErrorInfo(e, "Booking", "Detail");
				return View(Factory.VERROR, err);
			}
		}

		public ActionResult DetailSave(Booking booking)
		{
			try
			{
				if (!ModelState.IsValid)
				{
                    return this.Detail(booking.id.ToString());
				}

				BookingModel model = new BookingModel();

				if (booking.id < 1)
				{
					model.CreateBooking(booking);
				}
				else
				{
					model.SaveBooking(booking);
				}

				return RedirectToAction("Index", "Booking");
			}
			catch (Exception e)
			{
				HandleErrorInfo err = new HandleErrorInfo(e, "Booking", "Detail");
				return View(Factory.VERROR, err);
			}
		}

		public ActionResult CancelBooking(string bookingid)
		{
			try
			{
				int bookingID = ARMSConverter.ToInt(bookingid, Helper.DummyValue, false);
				BookingModel model = new BookingModel();

				Booking booking = model.FindBooking(bookingID);

				return View("CancelBooking", booking);
			}
			catch (Exception e)
			{
				HandleErrorInfo err = new HandleErrorInfo(e, "Booking", "CancelBooking");
				return View(Factory.VERROR);
			}
		}
	}
}